"""
实现状态对象或者状态机

问题：
   你想实现一个状态机或者是在不同状态下执行操作的对象，但是又不想在代码中出现太多的条件判断语句。
解决方案：
   在很多程序中，有些对象会根据状态的不同来执行不同的操作。
"""


class Connection:
    """
    对每个状态定义一个类
    """

    def __init__(self):
        self.new_state(CloseConnectionState)

    def new_state(self, state):
        self._state = state

    def read(self):
        return self._state.read(self)

    def write(self, data):
        return self._state.write(self, data)

    def open(self):
        return self._state.open(self)

    def close(self):
        return self._state.close(self)


class ConnectionState:
    """
    连接状态基类
    """

    @staticmethod
    def read(conn):
        raise NotImplementedError()

    @staticmethod
    def write(conn, data):
        raise NotImplementedError()

    @staticmethod
    def open(conn):
        raise NotImplementedError()

    @staticmethod
    def close(conn):
        raise NotImplementedError()


class CloseConnectionState(ConnectionState):
    @staticmethod
    def read(conn):
        raise RuntimeError("Not open")

    @staticmethod
    def write(conn, data):
        raise RuntimeError("Not open")

    @staticmethod
    def open(conn):
        conn.new_state(OpenConnectionState)

    @staticmethod
    def close(conn):
        raise RuntimeError("Already closed")


class OpenConnectionState(ConnectionState):
    @staticmethod
    def read(conn):
        print("reading")

    @staticmethod
    def write(conn, data):
        print("writing", data)

    @staticmethod
    def open(conn):
        raise RuntimeError("Already open")

    @staticmethod
    def close(conn):
        conn.new_state(CloseConnectionState)


def use_connection():
    conn = Connection()
    conn.open()
    print(conn._state)
    conn.write("没有背景的人需要加倍地努力")
    conn.close()
    print(conn._state)
    # 输出结果：
    """
    <class '__main__.OpenConnectionState'>
    writing 没有背景的人需要加倍地努力
    <class '__main__.CloseConnectionState'>
    """


if __name__ == '__main__':
    use_connection()
